﻿package com.cw.war.ui
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import net.libra.ui.EasyButton;


	/**
	 * 当选择改变时，发送此事件
	 * @eventType com.gjy.cq.plaf.CqFrame.ON_CLOSE
	 */
	[Event(name="SELECTION_CHANGED", type="com.cw.war.ui.ButtonScrollPane")]

	/**
	 * 按钮滚动面板。
	 * @author DanielLu
	 */
	public class ButtonScrollPane extends EventDispatcher
	{
		/**
		 *  <code>ButtonScrollPane.SELECTION_CHANGED</code> 常量定义 <code>selectionChanged</code> 事件对象的<code>type</code>属性值.
		 *
		 *  <p>此事件具有以下属性：</p>
		 *  <table class="innertable">
		 *     <tr><th>属性</th><th>值</th></tr>
		 *     <tr><td><code>bubbles</code></td><td>false</td></tr>
		 *     <tr><td><code>cancelable</code></td><td>false；没有要取消的默认行为。</td></tr>
		 *     <tr><td><code>currentTarget</code></td><td>当前正在使用某个事件侦听器处理 Event 对象的对象。 </td></tr>
		 *     <tr><td><code>target</code></td><td>发送事件的对象。</td></tr>
		 *  </table>
		 *  @eventType SELECTION_CHANGED
		 */
		public static const SELECTION_CHANGED : String = "selectionChanged";
		public static const ON_SCROLLNEXT : String = "onScrollNext";
		public static const ON_SCROLLPREV : String = "onScrollPrev";

		// ------------------------------------------------ui
		private var nextBtn : EasyButton;
		private var prevBtn : EasyButton;
		private var viewport : MaskedSprite;
		protected var content : Sprite;
		private var cellClass : Class;
		private var cells : Array;
		private var cellWidth : int;
		// ------------------------------------------------layout
		private var hGap : int;
		private var vGap : int;
		private var margin : Boolean;
		private var row : int;
		private var column : int;
		//
		private var pageGap : int;
		// ------------------------------------------------数据
		protected var listData : Array;
		protected var currentIndex : int;
		protected var selectedIndex : int;

		/**
		 * 创建一个按钮滚动面板。
		 * @param leftBtn		往左滚动的按钮影片剪辑。
		 * @param rightBtn		往右滚动的按钮影片剪辑。
		 * @param viewport		视口遮罩。
		 * @param cellClass		单元格渲染类。
		 */
		public function ButtonScrollPane ( nextBtn : MovieClip , prevBtn : MovieClip , viewport : DisplayObjectContainer , cellClass : Class , cellWidth : int = - 1 )
		{
			super ();
			//
			this.nextBtn = EasyButton.createEasyButton ( nextBtn );
			this.nextBtn.addEventListener ( MouseEvent.CLICK , this.__onScrollNext );
			//
			this.prevBtn = EasyButton.createEasyButton ( prevBtn );
			this.prevBtn.addEventListener ( MouseEvent.CLICK , this.__onScrollPrev );
			//
			this.viewport = new MaskedSprite ();
			this.viewport.setMaskBound ( 0 , 0 , viewport.width , viewport.height );
			this.viewport.x = viewport.x;
			this.viewport.y = viewport.y;
			viewport.parent.addChildAt ( this.viewport , viewport.parent.getChildIndex ( viewport ) );
			viewport.parent.removeChild ( viewport );

			this.content = new Sprite ();
			this.viewport.addChild ( this.content );
			//
			this.cellClass = cellClass;
			this.cells = new Array ();
			this.cellWidth = cellWidth;
			//
			this.hGap = 0;
			this.vGap = 0;
			this.margin = false;
			this.row = 0;
			this.column = 0;
			this.currentIndex = 0;
		}

		private function __onScrollNext ( e : Event ) : void
		{
			this.scrollNext ();
		}

		private function __onScrollPrev ( e : Event ) : void
		{
			this.scrollPrev ();
		}

		// ----------------------------------------------------------
		/**
		 * 设置是否Margin
		 */
		public function setMargin ( b : Boolean ) : void
		{
			this.margin = b;
		}

		/**
		 * 返回是否Margin
		 */
		public function isMargin () : Boolean
		{
			return this.margin;
		}

		/**
		 * 设置水平间隔。
		 */
		public function setHGap ( hGap : int ) : void
		{
			this.hGap = hGap;
		}

		public function getHGap () : int
		{
			return this.hGap;
		}

		/**
		 * 设置垂直间隔。
		 */
		public function setVGap ( vGap : int ) : void
		{
			this.vGap = vGap;
		}

		public function getVGap () : int
		{
			return this.vGap;
		}

		/**
		 * 设置布局时几行几列。
		 * @param row		行数
		 * @param column	列数
		 */
		public function setRowAndColumn ( row : int , column : int ) : void
		{
			this.row = row;
			this.column = column;
		}

		public function setRow ( row : int ) : void
		{
			this.row = row;
		}

		public function getRow () : int
		{
			return this.row;
		}

		public function setColumn ( column : int ) : void
		{
			this.column = column;
		}

		public function getColumn () : int
		{
			return this.column;
		}

		/**
		 * 设置页与页的间隔
		 */
		public function setPageGap ( pageGap : int ) : void
		{
			this.pageGap = pageGap;
		}

		public function getPageGap () : int
		{
			return this.pageGap;
		}

		/**
		 * 返回当前选择的索引。
		 */
		public function getSelectedIndex () : int
		{
			return this.selectedIndex;
		}

		/**
		 * 返回指定索引的数据。
		 */
		public function getValueAt ( index : int ) : *
		{
			var cell : ButtonScrollCell = this.cells[index];
			return cell.getValue ();
		}

		/**
		 * 设置要显示的数据。
		 * @param listData	要显示的数据。
		 */
		public function setListData ( listData : Array ) : void
		{
			// 复制数据源
			this.listData = listData;
			this.currentIndex = 0;
			this.selectedIndex = - 1;
			this.paint ();
		}

		/**
		 * 绘制内容
		 */
		private function paint () : void
		{
			// 清空容器
			while (this.content.numChildren > 0)
			{
				this.content.removeChildAt ( 0 );
			}
			this.content.x = this.content.y = 0;
			//
			var bx : int = this.margin ? this.hGap : 0;
			var by : int = this.margin ? this.vGap : 0;
			var tx : int = bx;
			var ty : int = by;
			//
			var bColumnCount : int = 0;
			var bRowCount : int = 1;
			var columnCount : int = bColumnCount;
			var rowCount : int = bRowCount;
			//
			var index : int;
			for (index = 0; index < this.cells.length ; index ++)
			{
				this.uninstallCell ( this.cells[index] );
			}
			// 循环显示单元格
			for (index = 0; index < this.listData.length ; index ++)
			{
				var cell : ButtonScrollCell = this.installCell ( index , this.listData[index] );
				var dis : DisplayObject = cell.getCellDisplayObject ();
				this.content.addChild ( dis );
				if (this.cellWidth == - 1) this.cellWidth = dis.width;
				dis.x = tx;
				dis.y = ty;
				columnCount ++;
				// 计算坐标
				if (columnCount < this.column)
				{
					tx += this.cellWidth + this.hGap;
				}
				else
				{
					columnCount = 0;
					rowCount ++;
					tx = bx;
					ty += dis.height + this.vGap;
				}
				// 如果行数超过了限制，将在下一页显示
				if (rowCount > this.row)
				{
					columnCount = bColumnCount;
					rowCount = bRowCount;
					// 重新计算初始点
					bx += this.cellWidth * this.column + this.hGap * (this.column - 1);
					bx += this.margin ? this.hGap : 0;
					bx += this.pageGap;
					bx += this.margin ? this.hGap : 0;
					by = by;
					//
					tx = bx;
					ty = by;
				}
			}
			// 设置按钮的状态
			this.nextBtn.setEnabled ( this.listData.length > this.row * this.column );
			this.prevBtn.setEnabled ( false );
		}

		/**
		 * 重绘
		 */
		public function repaint () : void
		{
			for (var i : int = 0; i < this.listData.length ; i ++)
			{
				var cell : ButtonScrollCell = this.cells[i];
				cell.setValue ( this.listData[i] , i );
			}
		}

		private function installCell ( index : int , data : * ) : ButtonScrollCell
		{
			var cell : ButtonScrollCell;
			if (this.cells[index] == null)
			{
				cell = new cellClass ();
				this.cells[index] = cell;
			}
			else
			{
				cell = this.cells[index];
			}
			cell.getCellDisplayObject ()["index"] = index;
			cell.setValue ( data , index );
			cell.getCellDisplayObject ().addEventListener ( MouseEvent.CLICK , this.__onCellSelected );
			return cell;
		}

		private function uninstallCell ( cell : ButtonScrollCell ) : void
		{
			delete cell.getCellDisplayObject ()["index"];
			cell.getCellDisplayObject ().removeEventListener ( MouseEvent.CLICK , this.__onCellSelected );
		}

		private function __onCellSelected ( e : Event ) : void
		{
			var dis : DisplayObject = e.currentTarget as DisplayObject;
			this.selectedIndex = dis["index"];
			this.dispatchEvent ( new Event ( SELECTION_CHANGED ) );
		}

		/**
		 * 滚动到下一页
		 */
		public function scrollNext () : void
		{
			// 定位下一个cell的索引
			var nextCellIndex : int = this.currentIndex + this.row * this.column;
			if (nextCellIndex <= this.listData.length - 1)
			{
				var currentCell : DisplayObject = this.content.getChildAt ( this.currentIndex );
				var nextCell : DisplayObject = this.content.getChildAt ( nextCellIndex );
				// 处理按钮的外观
				// 如果到了最后一页
				var next : Boolean;
				var prev : Boolean = true;
				if (nextCellIndex + this.row * this.column > this.listData.length - 1)
				{
					next = false;
				}
				else
				{
					next = true;
				}

				this.nextBtn.setEnabled ( false );
				this.prevBtn.setEnabled ( false );

				// 计算x轴上的偏差值
				var distanceX : int = (nextCell.x - (this.margin ? this.hGap : 0)) - currentCell.x;
				this.currentIndex = nextCellIndex;
				TweenLite.to ( this.content , 0.3 , { x : this.content.x - distanceX , onComplete : __onTweenCompleted , onCompleteParams : [ next , prev , "next" ] } );
			}
		}

		private function __onTweenCompleted ( next : Boolean , prev : Boolean , direction : String ) : void
		{
			this.nextBtn.setEnabled ( next );
			this.prevBtn.setEnabled ( prev );
			if (direction == "next")
			{
				this.dispatchEvent ( new Event ( ON_SCROLLNEXT ) );
			}
			else
			{
				this.dispatchEvent ( new Event ( ON_SCROLLPREV ) );
			}
		}

		/**
		 * 滚动到上一页
		 */
		public function scrollPrev () : void
		{
			// 定位下一个cell的索引
			var prevCellIndex : int = this.currentIndex - this.row * this.column;
			if (prevCellIndex >= 0)
			{
				var currentCell : DisplayObject = this.content.getChildAt ( this.currentIndex );
				var prevCell : DisplayObject = this.content.getChildAt ( prevCellIndex );
				// 处理按钮的外观
				var next : Boolean = true;
				var prev : Boolean ;
				if (prevCellIndex == 0)
				{
					prev = false;
				}
				else
				{
					prev = true;
				}

				this.prevBtn.setEnabled ( false );
				this.nextBtn.setEnabled ( false );
				// 计算x轴上的偏差值
				var distanceX : int = currentCell.x - (prevCell.x - (this.margin ? this.hGap : 0));
				this.currentIndex = prevCellIndex;
				this.content.mouseEnabled = false;
				TweenLite.to ( this.content , 0.3 , { x : this.content.x + distanceX , onComplete : __onTweenCompleted , onCompleteParams : [ next , prev , "prev" ] } );
			}
		}

		public function addSelectionListener ( listener : Function , priority : int = 0 , useWeakReference : Boolean = false ) : void
		{
			this.addEventListener ( SELECTION_CHANGED , listener , false , priority , useWeakReference );
		}

		public function removeSelectionListener ( listener : Function ) : void
		{
			this.removeEventListener ( SELECTION_CHANGED , listener );
		}
	}
}
